

Berta.EditorManager.addPlugin(['File', 'EntryGallery'], new Class(function() {
	
	return {
		extend: Berta.Editor,
		pluginName: 'File',
		
		// defaults for this particular plugin
		defaults: {
			pluginOptions: {
				formats: false,
				// false -> all formats allowed
				// string list of formats, e.g., 'jpg,gif,png'
								
				restrictions: false, /* images and swf only */
				// false, undefined -> no restrictions
				// object -> { [minW], [minH], [maxW], [maxH] }, e.g., { minW: 100, maxW: 140 }
				// string -> settings group that contains minW, minH, maxW, maxH, e.g., "templateSettings.logoSize"
 
 				caption: 'Upload',
				captionChange: 'Change',
				captionUploading: 	'{size}Kb - ',
				captionComplete:	'Complete!',
				
				// EntryGallery specific params:
				
				entryId: null
 
				// see defaults.pluginOptions in Berta.Editor class for inherited options
			}
		},
		
		uplodURL: null,
		uploadContainerVarName: null,
		uploadVarName: null,
		uploadParams: null,
		uploadMethod: 'put', 	// 'put' for one-file settings, 'post' for galleries
		
		isUploading: false,
		
		
		constructor: function(options) {
			// call the parent with pluginName=null
			// Editor defaults get extended by this.defaults and then extended by options
			Berta.Editor.call(this, options);
			
			this.originalValue = this._(getValueFromElement)();
			this.value = this.originalValue;
			
			if(this.options.type === 'EntryGallery') {
				this.uploadMethod = 'post';
				
			} else {
				this.uploadMethod = 'put';
			}
		},
		
		
		//   .______    __    __  .______    __       __    ______    ////////////////////////////////////////////////////////////
		//   |   _  \  |  |  |  | |   _  \  |  |     |  |  /      |   ////////////////////////////////////////////////////////////
		//   |  |_)  | |  |  |  | |  |_)  | |  |     |  | |  ,----'   ////////////////////////////////////////////////////////////
		//   |   ___/  |  |  |  | |   _  <  |  |     |  | |  |        ////////////////////////////////////////////////////////////
		//   |  |      |  `--'  | |  |_)  | |  `----.|  | |  `----.   ////////////////////////////////////////////////////////////
		//   | _|       \______/  |______/  |_______||__|  \______|   ////////////////////////////////////////////////////////////
		
		on: /* API */ function() {
			var cssClass = this.options.type === 'Gallery' ? 'x-editable-gallery' : 'x-editable-file';
			this.element.addClass('x-editable-on ' + cssClass);
			if(this.value === '') this.element.addClass('x-editable-empty');
			
			this._(addDropField)();
			this.appendPlaceholderIfEmpty(undefined, undefined, this._(detectIfElementIsEmpty));
			Berta.Editor.prototype.on.call(this);
		},
		
		off: /* API */ function() {
			if(this.hasFlag(Berta.Editor.flags.EDITING)) {
				this.cancel();
			}
			this._(removeDropField)();
			this.element.removeClass('x-editable-on x-editable-file x-editable-gallery x-editable-file-uploading x-editable-empty ');
			//this.element.unbind('click' + this.namespace());
			Berta.Editor.prototype.off.call(this);
		},
		
		edit: /* API */ function() {
			if (this.hasFlag(Berta.Editor.flags.ON) && !this.hasFlag(Berta.Editor.flags.EDITING)) {
				this.element.addClass('x-editing');
				this._(addFinishTrigger)();
				Berta.Editor.prototype.startEditing.call(this);
				Berta.Editor.prototype.setPanelContext.call(this);
			}
		},
		save: /* API */ function() {
			if (this.hasFlag(Berta.Editor.flags.EDITING)) {
				Berta.Editor.prototype.hidePanelContext.call(this);
				this._(removeFinishTrigger)();
				Berta.Editor.prototype.stopEditing.call(this);
				
				if (this.options.type === 'EntryGallery') {
					this.entryGallery_reload();
				}
			}
		},
		
		cancel: /* API */ function() {
			if (this.hasFlag(Berta.Editor.flags.EDITING)) {
				Berta.Editor.prototype.hidePanelContext.call(this);
				this.element.removeClass('x-editing');
				this._(removeFinishTrigger)();
				Berta.Editor.prototype.stopEditing.call(this);
				
			} else if (this.hasFlag(Berta.Editor.flags.ON) && this.isUploading) {
				Berta.Server.instance().cancelUpload(this.uploadId);
			}  
			
			this.cleanup();
		},
		
		destroy: function() {
			this.setFlag(Berta.Editor.flags.DESTROYING);
			this.cancel();
		},

		cleanup: function() {
			if(this.hasFlag(Berta.Editor.flags.DESTROYING)) {
				this.off();
			}
		},
		

		validate: /* override */ function() {
			Berta.Editor.prototype.validate.call(this);
			
			// TODO: process restrictions...
			// TODO: process derivatives...
		},
		getEmptyPlaceholder: /* override */ function(caption) {
			return '';
		},
		
		
		
		entryGallery_reload: function() {
			Berta.Controller.execCommand("controller:reloadEditable", 
										 this.element,
										 Berta.Route.get('get:snippet-entry-gallery', { 'id': this.options.pluginOptions.entryId }));
		}

		
	};
	
	
	
	
	//   .______   .______     __  ____    ____  ___   .___________. _______    //////////////////////////////////////////////////
	//   |   _  \  |   _  \   |  | \   \  /   / /   \  |           ||   ____|   //////////////////////////////////////////////////
	//   |  |_)  | |  |_)  |  |  |  \   \/   / /  ^  \ `---|  |----`|  |__      //////////////////////////////////////////////////
	//   |   ___/  |      /   |  |   \      / /  /_\  \    |  |     |   __|     //////////////////////////////////////////////////
	//   |  |      |  |\  \--.|  |    \    / /  _____  \   |  |     |  |____    //////////////////////////////////////////////////
	//   | _|      | _| `.___||__|     \__/ /__/     \__\  |__|     |_______|   //////////////////////////////////////////////////
	
	function detectIfElementIsEmpty(el) {
		var h = el.html();
		h = h.replace(/\&nsp;/, '');
		if(h === '' || jQuery.trim(h) === '') {
			return true;
		}
		return false;
	}
	
	function addDropField() {
		var txt = this.value !== '' ? this.options.pluginOptions.captionChange : this.options.pluginOptions.caption;
		var showFileField = this.value === '' || this.options.type === 'File';
		var multipleAttribute = this.options.type === 'File' ? '' : 'multiple="multiple"';
		this.uploadContainer = $('<div class="x-editable-file-drop">' + 
				'<span class="x-editable-file-caption">' + txt + '</span>' + 
				(showFileField 
					? ('<span class="x-editable-file-progress x-hidden"><div></div><span></span></span>' + 
					   '<div class="x-editable-file-input"><input type="file" size="80" ' + multipleAttribute + ' /></div>')
					: ''
				) + 
		'</div>');
		
		if (this.options.type !== 'EntryGallery' || this.value === '') {
			// for simple file editables, some resizing must be done
			this.elementOrigPosition = this.element.css('position');
			if(this.elementOrigPosition == 'static') this.element.css('position', 'relative');
		}
	
		this.element.append(this.uploadContainer);
		
		this.uploadCaption = this.uploadContainer.find('.x-editable-file-caption:first');
		this.uploadProgress = this.uploadContainer.find('.x-editable-file-progress:first');
		this.uploadField = this.uploadContainer.find('input:first')
											   .bind('change' + this.namespace(), this._(onInputChange))
		
		if(!showFileField) {
			this.uploadCaption.bind('click' + this.namespace(), this._(onGalleryEditClick));
		}
		
	}
	function removeDropField() {
		this.uploadField.unbind(this.namespace());
		this.uploadContainer.find('div>div').unbind(this.namespace());
		this.uploadContainer.empty().remove();
		this.uploadCaption = undefined;
		this.uploadProgress = undefined;
		this.uploadField = undefined;
		this.uploadContainer = undefined;
		
		if(this.elementOrigPosition)
			this.element.css('position', this.elementOrigPosition);
	}
	
	
	function onGalleryEditClick(event) {
		this.edit();
		return false;
	}
	
	function onInputChange(event) {
		this.isUploading = true;
		this.uploadCaption.addClass('x-hidden');
		this.uploadField.addClass('x-hidden');
		this.uploadProgress.removeClass('x-hidden');
		this.uploadProgress.children('div').css('width', 0);
		this.uploadProgress.children('span').text('Uploading ...');

		var data = {};
		data[this.options.variable] = event.target.files;

		this.uploadId = Berta.Server.instance().upload(
			this.uploadMethod,
			Berta.Route.get(this.options.route, null, data, this.options.params),
			{ callbacks: {
					onStart: this._(onUploadStart),
					onProgress: this._(onUploadProgress),
					onComplete: this._(onUploadComplete),
					onFileComplete: this._(onUploadFileComplete),
					onFileErorr: this._(onUploadFileError)
			} }
		);
	}
	function onUploadStart(totalBytes) {
		this.element.addClass('x-editable-file-uploading');
		this.defaultUploadProgress = this.options.pluginOptions.captionUploading.replace(/\{size\}/, Math.round(totalBytes / 1024)); //'Uploading ' + Math.round(totalBytes / 1024) + 'Kb';
		this.uploadProgress.children('span').html(this.defaultUploadProgress + ' ...');
	}
	function onUploadProgress(file, fileProgress, overallProgress) {
		this.uploadProgress.children('div').animate({ 'width': Math.round(overallProgress * 100) + '%' }, 500);
		this.uploadProgress.children('span').html(this.defaultUploadProgress + Math.round(overallProgress * 100) + '%');
		//$.log(this.defaultUploadProgress + ' - ' + Math.round(overallProgress * 100) + '%');
	}
	function onUploadFileError(file) {
		
	}
	function onUploadFileComplete(file, response) {
		if(this.options.type === 'File') {
			
			// Variable is in form [command]:[variable] (e.g., /settings:test.image)
			var expectedResultKey = this.options.variable.split(':').pop();
			
			if(response.json.values && response.json.values[expectedResultKey]) {
				this.element.find('.x-editable-file-file').html(response.json.values[expectedResultKey]);
			}
		}
	}
	function onUploadComplete(totalBytes) {
		this.isUploading = false;
		this.uploadId = false;
		
		this.uploadProgress.children('div').animate({ 'width': '100%' }, 150);
		this.uploadProgress.children('span').html(this.defaultUploadProgress + this.options.pluginOptions.captionComplete);
		
		setTimeout(this._(finishFileUpload), 1000);
	}
	
	function finishFileUpload() {
		if (this.options.type === 'EntryGallery') {
			this.entryGallery_reload();
		
		} else {
			this.uploadProgress.addClass('x-hidden');
			
			this.uploadCaption.html(this.options.pluginOptions.captionChange)
							  .removeClass('x-hidden');
			this.uploadField.removeClass('x-hidden');
			
			this.element.removeClass('x-editable-file-uploading');
		}
	}
	
	
	

	function getValueFromElement(){
		
		// For gallery check if there are any images or objects � in that case set value to TRUE
		if(this.options.type === 'Gallery') {
			var imgs = this.element.find('.x-editable-gallery-images img:first');
			if (imgs.length > 0) 
				return true;
			
			var objs = this.element.find('.x-editable-gallery-images object:first');
			if (objs.length > 0)
				return true;
		
			return false;	// no images or media
		}
		
		// For File editable return contents of the file name container
		var val = this.element.find('.x-editable-file-file').html();
		
		return val;
		
	}
	
	
	
	
	
	
	function addFinishTrigger() {
		// adds click event to the body that checks if the user has clicked outside the replacementElement
		this._onBodyClick = this._(onBodyClick);
		//$(document.body)[0].addEventListener('click', this._onBodyClick, true); // add to capturing phase
		$('html')[0].addEventListener('click', this._onBodyClick, true); // add to capturing phase
	}
	function removeFinishTrigger() {
		// adds click event to the body that checks if the user has clicked outside the replacementElement
		$('html')[0].removeEventListener('click', this._onBodyClick, true);
		this._onBodyClick = null;
		//$(document.body).unbind('click' + this.namespace());
	}
	function onBodyClick(event) {
		// captures the "click" event and checks if the click has happened
		// outside the replacementElement. if yes, then stopEditing()
		var trg = $(event.target);
		//console.debug(this, trg);
		
		if(this.options.context != 'panel' && trg.xInPanelOrPopups()) {
			// clicked on panel while editing outside panel
			// don't touch the event
			return true;
			
		} else {
			// if clicked anywhere outside gallery - cancel editing!
			event.stopPropagation();
			event.preventDefault();
			if(trg != this.element && trg.parents('.x-editable-file').get(0) != this.element.get(0)) {
				this.save();
			}
			return false;
		}
	}
	
	
	
}()));



